package b.utils.entity

import akka.Done
import com.lightbend.lagom.scaladsl.persistence.PersistentEntityRegistry

import scala.concurrent.{ExecutionContext, Future}

/**
  * 贲国称 于 2017/1/20 创建。
  */
trait T事务ServiceImpl {
  def fTCC(registry: PersistentEntityRegistry, x事务ID: Long, v事务名称: String, v参与方s: Map[String, T事务参与方[_]])
          (implicit ex: ExecutionContext): Future[Done] = {
    val xa = registry.refFor[C事务PersistentEntity](s"/TCC/$x事务ID")
    xa.ask[CC事务Start](CC事务Start(x事务ID, v事务名称, v参与方s))
      .flatMap { _ =>
        val tries = v参与方s map { p =>
          p._2.f尝试 flatMap { _ =>
            xa.ask[CC事务参与方Try](CC事务参与方Try(x事务ID, p._1))
          }
        }
        Future.sequence(tries) flatMap { _ =>
          val confirms = v参与方s map { p =>
            p._2.f确认 flatMap { _ =>
              xa.ask[CC事务参与方Confirm](CC事务参与方Confirm(x事务ID, p._1))
            }
          }
          Future.sequence(confirms) flatMap { _ =>
            xa.ask[CC事务Commit](CC事务Commit(x事务ID))
          }
        }
      }
      .recover { case t: Throwable =>
        println(t)
        val cancels = v参与方s.map { p =>
          p._2.f取消 flatMap { _ =>
            xa.ask[CC事务参与方Cancel](CC事务参与方Cancel(x事务ID, p._1))
          }
        }
        Future.sequence(cancels) flatMap { _ =>
          xa.ask[CC事务Rollback](CC事务Rollback(x事务ID))
        }
        throw t
      }
  }

}
